package cn.com.ctbri.geomonitor.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.portlet.bind.annotation.ResourceMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.parser.deserializer.StringFieldDeserializer;
import com.mysql.fabric.ShardingType;

import cn.com.ctbri.geomonitor.bean.VacationForm;
import cn.com.ctbri.geomonitor.bean.departmentTask;
import cn.com.ctbri.geomonitor.bean.finishVO;
import cn.com.ctbri.geomonitor.model.FlowName;
import cn.com.ctbri.geomonitor.model.Program;
import cn.com.ctbri.geomonitor.service.ProcessRestService;
import cn.com.ctbri.geomonitor.service.UserRestService;
import cn.com.ctbri.geomonitor.utils.SystemConstants;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Attachment;
import org.apache.http.HttpRequest;

import cn.com.ctbri.geomonitor.bean.BaseForm;
import cn.com.ctbri.geomonitor.bean.CommentVO;
import cn.com.ctbri.geomonitor.bean.FormField;
import cn.com.ctbri.geomonitor.bean.ProXuanZhiForm;
import cn.com.ctbri.geomonitor.bean.ProcessVO;
import cn.com.ctbri.geomonitor.bean.TaskDetial;
import cn.com.ctbri.geomonitor.bean.TaskVO;

@Controller
public class ProcessRestController {
	@Resource(name = "processRestService")
	ProcessRestService processRestService;
	
	@Resource(name = "userRestService")
	UserRestService userRestService;


	@Resource(name = "taskService")
	private TaskService taskService;
	// 流程类型
	private String processType;
	// 任务评论
	private List<CommentVO> comments;
	// 需要显示的表单域
	private List<FormField> formFields;
	// 任务类型
	private String taskType;

	private String errorMsg;

	private List<ProcessVO> processes;

	private String taskId;

	private List<TaskVO > tasks;

	// 部署流程
	@RequestMapping(value = "process/deployProcess")
	public void deployProcess() {
		// 创建流程引擎
		ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
		// 得到流程存储服务对象
		RepositoryService repositoryService = engine.getRepositoryService();
		// 创建DeploymentBuilder实例
		DeploymentBuilder builder = repositoryService.createDeployment();
		builder.addClasspathResource("bpmn/KexingxingYanjiuBaogao.bpmn").deploy();
		// 此处error.bpmn不是流程描述文件，这里将会抛出 ：
		// couldn't parse 'bpmn/error.bpmn': Premature end of file.
	}

	// 启动请假流程
//	@ResponseBody
//	@RequestMapping(value = "process/startVacation", method = RequestMethod.POST, produces = "text/html; charset=utf-8")
//	public String startVacation(VacationForm vacationForm, HttpSession session,
//			@RequestParam("file1") MultipartFile[] file1, HttpServletRequest request) {
//
//		ProcessInstance pi = this.processRestService.startVacation(vacationForm, file1, request);
//		this.processType = BaseForm.VACATION;
//
//		return "startVacation";
//
//	}

	// 启动选址意见书流程
//	@RequestMapping(value = "process/startProXuanZhi", method = RequestMethod.POST)
//	public String startProXuanZhi(HttpSession session, @RequestParam("file1") MultipartFile[] file1,
//			ProXuanZhiForm proxuanzhi, HttpServletRequest request) {
//
//		ProcessInstance pi = this.processRestService.startProXuanZhi(file1, proxuanzhi, request);
//		return "startProXuanZhi";
//
//	}

	//启动流程
	@RequestMapping(value = "process/startProcess", method = RequestMethod.POST)
	public ModelAndView startProcess(HttpSession session, @RequestParam("file1") MultipartFile[] file1,
			@RequestParam("programName") String programName, HttpServletRequest request,@RequestParam("type") String type,HttpServletResponse response
) {
		// 从session中拿回登录的用户
		
		User user = (User) session.getAttribute(SystemConstants.SESSION_USER);
		ProcessInstance pi = this.processRestService.startProcess(file1,type, request,user.getId(),programName);
//		try {
//			response.sendRedirect( request.getContextPath()+"/process/getAllApply");
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		return getAllApply(session);

	}
	
	
	
	// 读取登录用户的全部申请
	@ResponseBody
	@RequestMapping(value = "process/listProXuanZhi", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public ModelAndView listProcessInstance(@RequestParam("processType") String processType, HttpSession httpSession) {
		// 从session中拿回登录的用户
		User user = (User) httpSession.getAttribute(SystemConstants.SESSION_USER);
		ModelAndView modelAndView = new ModelAndView();
		// 获取流程类型
		if (BaseForm.VACATION.equals(processType)) {
			this.processes = this.processRestService.listVacation(user.getId());
		}
		if (BaseForm.PROXUANZHI.equals(processType)) {
			this.processes = this.processRestService.listProXuanZhi(user.getId());
		}
		modelAndView.addObject("processes", processes);
		modelAndView.setViewName("processing");
		return modelAndView;
	}

 	@ResponseBody
	@RequestMapping(value = "process/showDiagram", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public void showDiagram(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse response,
			HttpServletRequest request) {
		OutputStream out = null;
		try {
			// HttpServletResponse response =
			// ServletActionContext.getResponse();
			InputStream is = processRestService.getDiagram(processInstanceId);
			response.setContentType("multipart/form-data;charset=utf8");
			out = response.getOutputStream();
			out.write(getImgByte(is));
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}
		//List<Attachment> attachments = processRestService.getAttachments(processInstanceId);
		
	}

	// 将输入流转换为byte数组
	private byte[] getImgByte(InputStream is) throws IOException {
		ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
		int b;
		while ((b = is.read()) != -1) {
			bytestream.write(b);
		}
		byte[] bs = bytestream.toByteArray();
		bytestream.close();
		return bs;
	}

	// 查询任务
	@ResponseBody
	@RequestMapping(value = "process/listTask", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public ModelAndView listTask(@RequestParam("taskType") String taskType, HttpSession session) {
		ModelAndView modelAndView = new ModelAndView();
		// 从session中拿回登录的用户
		User user = (User) session.getAttribute(SystemConstants.SESSION_USER);
		if ("candidate".equals(taskType)) {
			// 查询待办任务
			this.tasks = this.processRestService.listTasks(user.getId());
			modelAndView.addObject("tasks", tasks);

		} else if ("assignee".equals(taskType)) {
			// 查询受理的任务
			this.tasks = this.processRestService.listAssigneeTasks(user.getId());
			modelAndView.addObject("tasks", tasks);

		}else if ("history".equals(taskType)) {
			//根据用户Id查询办理的任务的历史
			List<departmentTask> daTaskInstances = processRestService.getHistoryOfTask(user.getId());
			modelAndView.addObject("historyTask", daTaskInstances);
			
			
					}
		modelAndView.addObject("taskType", taskType);
		Group group =  processRestService.getGroupID(user.getId());
		if(group.getType().equals("企业")){
		modelAndView.setViewName("myTask");
		}else {
			modelAndView.setViewName("TaskMenu");

		}
		
		return modelAndView;
	}

	// "领取任务
	@ResponseBody
	@RequestMapping(value = "process/claim")
	public ModelAndView claim(HttpSession session, @RequestParam("taskId") String taskId) {
		ModelAndView modelAndView = new ModelAndView();
		User user = (User) session.getAttribute(SystemConstants.SESSION_USER);
		this.processRestService.claim(taskId, user.getId());
		
		return listTask("candidate", session);
	}

	// 打开办理页面
	@ResponseBody
	@RequestMapping(value = "process/perform", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public ModelAndView perform(@RequestParam("taskId") String taskId, @RequestParam("processInstanceId") String pi,HttpSession httpSession) {
		ModelAndView modelAndView = new ModelAndView();
		this.comments = this.processRestService.getComments(taskId);
		//this.formFields = this.processRestService.getFormFields(taskId);
		List<Program> programs = processRestService.getApplyByPi(pi);
		List<Attachment> attachments = processRestService.getAttachments(pi);
		List<Attachment> userAttachments = new ArrayList<Attachment>();
		List<Attachment> departmentAttachments = new ArrayList<Attachment>();
		for(Attachment attachment : attachments){
			if(attachment.getDescription().equals("用户提交的申请材料")){
				userAttachments.add(attachment);
			}else{
				departmentAttachments.add(attachment);
			}
				
		}

		modelAndView.addObject("taskId", taskId);
		modelAndView.addObject("comments", comments);
		//modelAndView.addObject("formFields", formFields);
		modelAndView.addObject("programs", programs);
		modelAndView.addObject("programName",programs.get(0).getProName());
		modelAndView.addObject("userId",programs.get(0).getUserId());
		
		//modelAndView.addObject("pi",programs.get(0).getClass());


		modelAndView.addObject("programType",programs.get(0).getType());
		modelAndView.addObject("userAttachments", userAttachments);
		modelAndView.addObject("departmentAttachments", departmentAttachments);
		
		User user = (User) httpSession.getAttribute(SystemConstants.SESSION_USER);
		Group group =  processRestService.getGroupID(user.getId());
		if(group.getType().equals("企业")){
		modelAndView.setViewName("myMaterial");
		}else {
			modelAndView.setViewName("auditTask");

		}
		return modelAndView;
	}

	// 申请人完成任务
	@ResponseBody
	@RequestMapping(value = "process/complete", method = RequestMethod.POST, produces = "text/html; charset=utf-8")
	public ModelAndView complete(@RequestParam("taskId") String taskId,
			HttpSession httpSession) {
		ModelAndView modelAndView = new ModelAndView();
		User user = (User) httpSession.getAttribute(SystemConstants.SESSION_USER);

		processRestService.complete(taskId, user.getId());
		return listTask("assignee", httpSession);
	}

	// 窗口--业务股市--任务完成
	@RequestMapping(value = "process/processComplete", method = RequestMethod.POST, produces = "text/html; charset=utf-8")
	public ModelAndView complete1(@RequestParam("file") MultipartFile[] file,@RequestParam("taskId") String taskId,@RequestParam("programType") String programType,
			HttpSession httpSession,HttpServletRequest request,@RequestParam("programName") String programName,@RequestParam("userId") String userId,@RequestParam("content") String conent) {
		ModelAndView modelAndView = new ModelAndView();
	
		String select = request.getParameter("select");
		
		
		
		MultipartFile[] 	file11 = new  MultipartFile[1];
		for(int i= 0;i<file.length;i++){
			if(file[i].getOriginalFilename() != ""){
				file11[0] = file[i];
			}
		}
		
	
		User user = (User) httpSession.getAttribute(SystemConstants.SESSION_USER);
		
		

		processRestService.complete1(file11,taskId, select, user.getId(),request,programType,programName,userId,conent);
		this.taskType = TaskVO.ASSIGNEE;
		
		return listTask("assignee", httpSession);
	}
	
	// 附件下载
	@ResponseBody
	@RequestMapping(value = "process/downloadFiles", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
	public void downloadFiles(@RequestParam("url") String url, @RequestParam("filename") String filename,
			HttpServletResponse response, HttpServletRequest request) throws Exception {
		String fileName = request.getSession().getServletContext().getRealPath("upload");
		String[] url1 = url.split("/");

		for (int i = 0; i < url1.length; i++) {
			if (!(url1[i].equals("upload"))) {
				fileName = fileName + "/" + url1[i];
			}
		}

		File file = new File(fileName);
		if (file.exists()) {
			// 设置相应类型让浏览器知道用什么打开 用application/octet-stream也可以，看是什么浏览器
			response.setContentType("application/x-msdownload");
			// 设置头信息
			response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
			InputStream inputStream = new FileInputStream(file);
			ServletOutputStream ouputStream = response.getOutputStream();
			byte b[] = new byte[1024];
			int n;
			while ((n = inputStream.read(b)) != -1) {
				ouputStream.write(b, 0, n);
			}
			// 关闭流
			ouputStream.close();
			inputStream.close();
		} else {
			request.setAttribute("errorResult", "文件不存在,下载失败!");
			RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp");
			dispatcher.forward(request, response);
		}
	}
	//用户获取申请列表
		@ResponseBody
		@RequestMapping(value = "process/getAllApply")
		public ModelAndView getAllApply(HttpSession httpSession) {
			User user = (User) httpSession.getAttribute(SystemConstants.SESSION_USER);
			
		ModelAndView mv = new ModelAndView();
//			if(taskType.equals("apply")){
				List<FlowName> flowList = userRestService.getAllFlow();
				httpSession.setAttribute("flowList", flowList);
				
			//}
			List<TaskVO> applyList = processRestService.getAllApply(user.getId());
			List<HistoricProcessInstance> lInstances = processRestService.getFinishiedFlowByUserId(user.getId());
			List<finishVO> lists = new ArrayList<>();
			for(int i= 0;i<lInstances.size();i++){
				//根据proInstId查找流程
				Program program = processRestService.getProgramByProInstId(lInstances.get(i).getId());
				finishVO finish = new finishVO();
				//List<Program> programs= new ArrayList<>();
				//programs.add(program);
				//applyList.remove(processRestService.formatProgram(programs));
				SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				finish.setEndTime(simpleDateFormat.format(lInstances.get(i).getEndTime()));
				finish.setProgramName(program.getProName());
				finish.setProInstId(program.getProcInstId());
				finish.setStartTime(simpleDateFormat.format(lInstances.get(i).getStartTime()));
				finish.setType(program.getType());
				
				lists.add(finish);
				
			}
		
			mv.addObject("lists", lists);
			mv.addObject("applyList", applyList);
			mv.setViewName("myApply");
			return mv;
		}
	
		// 打开办理页面
		@ResponseBody
		@RequestMapping(value = "process/getMyMaterial", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
		public ModelAndView getMyMaterial( @RequestParam("processInstanceId") String pi) {
			ModelAndView modelAndView = new ModelAndView();
			this.comments = this.processRestService.getCommentsByPi(pi);
			//this.formFields = this.processRestService.getFormFields(taskId);
			List<Program> programs = processRestService.getApplyByPi(pi);
			List<Attachment> attachments = processRestService.getAttachments(pi);
			List<Attachment> userAttachments = new ArrayList<Attachment>();
			List<Attachment> departmentAttachments = new ArrayList<Attachment>();
			for(Attachment attachment : attachments){
				if(attachment.getDescription().equals("用户提交的申请材料")){
					userAttachments.add(attachment);
				}else{
					departmentAttachments.add(attachment);
				}
					
			}

			//modelAndView.addObject("formFields", formFields);
			modelAndView.addObject("comments",comments);
			modelAndView.addObject("programs", programs);
			modelAndView.addObject("programName",programs.get(0).getProName());
			
			modelAndView.addObject("userAttachments", userAttachments);
			modelAndView.addObject("departmentAttachments", departmentAttachments);
			modelAndView.setViewName("myMaterial");
			return modelAndView;
		}

	//查询历史数据
		@RequestMapping(value="process/getHistory")
		public ModelAndView getHistory(@RequestParam("type") String type){
			
			List<HistoricProcessInstance> datas = processRestService.getFinishedFlow(type);
			return null;
		}
		
		//更改文件
		@RequestMapping(value = "process/updateFile")
		public String  updateFile(@RequestParam("file1") MultipartFile[] file1, HttpServletRequest request,@RequestParam("url") String url,@RequestParam("taskI")String taskId){
			return null;
		}
	
	
	//管理员根据流程类型查找已经完成的流程
		@RequestMapping(value = "process/getFinishedFlowByType")
		public ModelAndView getFinishedFlowByType(@RequestParam("type") String type){
			ModelAndView modelAndView = new ModelAndView();
			List<HistoricProcessInstance> lInstances = processRestService.getFinishedFlowByType(type);
			List<finishVO> lists = new ArrayList<>();
			for(int i= 0;i<lInstances.size();i++){
				//根据proInstId查找流程
				Program program = processRestService.getProgramByProInstId(lInstances.get(i).getId());
				finishVO finish = new finishVO();
				SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				finish.setEndTime(simpleDateFormat.format(lInstances.get(i).getEndTime()));
				finish.setProgramName(program.getProName());
				finish.setProInstId(program.getProcInstId());
				finish.setStartTime(simpleDateFormat.format(lInstances.get(i).getStartTime()));
				finish.setType(program.getType());
				
				lists.add(finish);
				
			}
			List<FlowName> list = userRestService.getAllFlow();
			modelAndView.addObject("list", list);
			modelAndView.addObject("lists", lists);
			//modelAndView.addObject("param", "3");
			modelAndView.setViewName("historyTask");
			return modelAndView;
		}
	//管理员根据proInstId查找流程的明细
		@RequestMapping(value = "process/getTheDetailOfFlowByProInstId")
		public ModelAndView getTheDetailOfFlowByProInstId(@RequestParam("proInstId") String proInstId){
			ModelAndView modelAndView = new ModelAndView();
			
			List<HistoricTaskInstance> daTaskInstances=processRestService.getTheDetailOfFlowByProInstId(proInstId);
			List<TaskDetial> lists = new ArrayList<>();
			for(int i= 0;i<daTaskInstances.size();i++){
				//根据用户ID查找用户的名字
				String userName = userRestService.getUserByUserId(daTaskInstances.get(i).getOwner()).getLastName();
				
				TaskDetial taskDetial = new TaskDetial();
				SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				taskDetial.setEndTime(simpleDateFormat.format(daTaskInstances.get(i).getEndTime()));
				taskDetial.setStartTime(simpleDateFormat.format(daTaskInstances.get(i).getStartTime()));
				taskDetial.setTaskName(daTaskInstances.get(i).getName());
				taskDetial.setUserName(userName);
				
				lists.add(taskDetial);
				
			}
			modelAndView.addObject("lists", lists);
			modelAndView.setViewName("taskDeatil");
			return modelAndView;
		}
		
		
		// 查询任务
		@ResponseBody
		@RequestMapping(value = "process/myTask", method = RequestMethod.GET, produces = "text/html; charset=utf-8")
		public ModelAndView myTask(@RequestParam("taskType") String taskType, HttpSession session) {
			ModelAndView modelAndView = new ModelAndView();
			// 从session中拿回登录的用户
			User user = (User) session.getAttribute(SystemConstants.SESSION_USER);
			if ("candidate".equals(taskType)) {
				// 查询待办任务
				this.tasks = this.processRestService.listTasks(user.getId());
				modelAndView.addObject("tasks", tasks);

			} else if ("assignee".equals(taskType)) {
				// 查询受理的任务
				this.tasks = this.processRestService.listAssigneeTasks(user.getId());
				modelAndView.addObject("tasks", tasks);

			}
			modelAndView.addObject("taskType", taskType);
			modelAndView.setViewName("myTask");
			return modelAndView;
		}

}
